Skip to content

Enable resource cards on workload detail pages#17737

Draft
codyrancher wants to merge 7 commits into
rancher:masterfrom
codyrancher:issue-16375
Draft

Enable resource cards on workload detail pages#17737
codyrancher wants to merge 7 commits into
rancher:masterfrom
codyrancher:issue-16375

Conversation

@codyrancher
Copy link
Copy Markdown
Member

@codyrancher codyrancher commented May 19, 2026

Summary

Fixes #16375

Occurred changes and/or fixed issues

Workload detail pages now show resource cards (Pods, Services, Ingresses, relationships) without fetching full resource collections. State breakdowns come from the Steve summary API (?summary=metadata.state.name), and relationship rows read state directly from metadata.relationships.

Each workload type's Resources card only shows rows that correspond to its actual tabs:

  • Deployments, DaemonSets, StatefulSets: Services, Ingresses, relationships
  • CronJobs: Jobs (referred to by) only
  • Jobs: relationships only (no Services/Ingresses)

Pod detail pages now show a Containers row with state colors and an Insights card.

Technical notes summary

  • fetchResourceSummary - VAI-only store action. Returns undefined with a warning when VAI is disabled so callers degrade gracefully.
  • useResourceSummary - Reactive wrapper that refetches on generation(type) changes and cleans up via onScopeDispose, so consumers stay current without manual teardown.
  • useResourceCardRowFromSummary / FromRelationships - Reuse the same colorForState/stateDisplay mapping as resource models so summary-driven rows look identical to locally-computed ones.
  • StatusCard gains a summaryData prop; when present it takes precedence over resources.
  • _resourcesCardRows / resourcesCard on the base Resource class so all resource types get relationship cards for free.
  • matchingIngresses moved from the detail page component to the workload model so it is reactive and testable.
  • simpleColorForState extracted as a helper in resource-class.js for consistent state color handling without the text- prefix.
  • Relationship rows (_resourcesCardRows) now require fromId/toId, filtering out generic type-only references that produced phantom "missing" entries.

Areas or cases that should be tested

  • Deployment detail page: should show Pods, Resources (Services, Ingresses, relationships), and Insights cards
  • DaemonSet detail page: same as Deployment
  • StatefulSet detail page: same as Deployment; verify Services/Ingresses only appear when the workload actually has related services
  • CronJob detail page: Resources card should only show "Referred to by" (no Services/Ingresses)
  • Job detail page: Resources card should show "Referred to by" and "Refers to" (no Services/Ingresses)
  • Pod detail page: Resources card should show Containers with correct state colors, plus relationship rows; Insights card should appear
  • Non-workload resource detail pages show relationship-based Resources card

Areas which could experience regressions

  • Workload detail page load (parallel summary requests added during fetch)
  • Resource card rendering on types that override resourcesCardRows

Screenshot/Video

Demo (live update of resource counts)

demo.webm

Deployment

deployment

DaemonSet (with Services and Ingresses)

daemonset-resources

StatefulSet

statefulset

CronJob (with Jobs)

cronjob-with-jobs

Job

job

Pod

pod

Checklist

  • The PR is linked to an issue and the linked issue has a Milestone, or no issue is needed
  • The PR has a Milestone
  • The PR template has been filled out
  • The PR has been self reviewed
  • The PR has a reviewer assigned
  • The PR has automated tests or clear instructions for manual tests and the linked issue has appropriate QA labels, or tests are not needed
  • The PR has reviewed with UX and tested in light and dark mode, or there are no UX changes
  • The PR has been reviewed in terms of Accessibility
  • The PR has considered, and if applicable tested with, the three Global Roles Admin, Standard User and User Base

Comment thread shell/plugins/steve/actions.js Outdated
* @param {string} opt.namespaced - Namespace to scope the query to
* @returns {{ count: number, summary: Array<{ property: string, counts: Record<string, number> }> }}
*/
async fetchSummary({ getters, dispatch }, { type, opt = {} }) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should sync with @marcelofukumoto and make sure we're not duplicating methods of calling the summary endpoint.

think we should also make use of the typing PaginationParamFilter and to construct the url steve-pagination-utils.ts createParamsForPagination (convertPaginationParams)

this would also only work if the vai feature is enabled. in theory this will always be on from 2.16 so can choose to omit check?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, all fair points.

@marcelofukumoto it does look like you're fetching the summaries on the specific page .

By any chance is there any changes I could make to this action to make it useful for the workload pages? If you already have something more generic in the works I'd be happy to use that as well.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is great. I think we can just use your function! Mine is just on the composable of my page.
Not sure who will merge first, but as soon as you get yours merged I will update to use your function.

@codyrancher codyrancher force-pushed the issue-16375 branch 4 times, most recently from 905b0be to d575548 Compare May 20, 2026 21:11
Comment thread shell/plugins/steve/actions.js Outdated
@@ -221,6 +223,23 @@ export default {
}
},

async fetchSummary({ getters, dispatch, rootGetters }, { type, opt = {} }) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am debating whether or not to have this fetch locally as a fallback.

If we want to have a non-performant fallback I think it's better to have it here so that when we're in a vai always on world we won't have to update all of the call sites.

However, at least in the scenario I'm using it in it would be perfectly acceptable to just not show the cards if vai isn't on.

@codyrancher codyrancher force-pushed the issue-16375 branch 4 times, most recently from 7b5b4d0 to 0afe672 Compare May 20, 2026 21:43
Use the Steve summary API (?summary=metadata.state.name) to fetch
per-state counts for pods, services, and ingresses without loading
full resource collections. Relationship rows (Referred to by / Refers
to) read state directly from metadata.relationships.

Fixes rancher#16375
…omposable

Add a reactive composable that watches store generation for a resource
type and refetches summary data on changes. Cleans up automatically
via onScopeDispose when the component unmounts.
Cover initial fetch, undefined handling, reactive updates on
generation change, and automatic cleanup on scope disposal.
*
* Must be called during component setup.
*/
export function useResourceSummary(type: string, opt: ResourceSummaryOpt) {
Copy link
Copy Markdown
Member Author

@codyrancher codyrancher May 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is primarily here to facilitate live updates. It appears that the summary api doesn't work with the existing watching mechanism and this allows us to fairly performantly watch the summary counts.

- Fix broken reactivity in useDefaultResources (toValue inside computed)
- Fix division by zero in StatusCard percent function
- Fix race condition in useResourceSummary with fetchId staleness guard
- Fix inconsistent color assignment in StatusCard rowAccumulator
- Fix inconsistent sort comparator in useResourceCardRowFromRelationships
- Add color fallback for missing stateSimpleColor in StatusCard
- Add error handling for fire-and-forget async in useResourceSummary
- Parallelize service/ingress summary fetches with Promise.all
- Rename opt.namespaced to opt.namespace for clarity
- Replace hardcoded 'Resources' with i18n key
- Extract duplicated 'metadata.state.name' to constant
- Use nullish coalescing for res.count
- Fix JSDoc example to include required summaryField
- Use ?? instead of || for count/length in StatusCard computed
- Add .filter((c) => c) to workload cards getter for null safety
- Initialize summaries.pods = null explicitly when no pod selector
- Use normalizedType in useResourceSummary dispatch for consistency
- Gate Services/Ingresses rows to only Deployments, DaemonSets, and
  StatefulSets (not Jobs or CronJobs which lack those tabs)
- Remove namespace-wide summary fallback that showed incorrect counts
- Filter relationship rows to require specific resource IDs, preventing
  phantom "missing" entries from generic type references
- Add Containers row and Insights card to Pod detail page
- Extract simpleColorForState helper for consistent state color usage

Fixes rancher#16375
@codyrancher codyrancher deleted the issue-16375 branch May 21, 2026 18:00
Fixes TS2554 build error where callers passed only the state argument.

Fixes rancher#16375
@codyrancher codyrancher reopened this May 21, 2026
@codyrancher codyrancher requested a review from rak-phillip May 21, 2026 21:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Resource Detail: Add the Resources Card to the detail pages

3 participants